bitkeeper revision 1.183 (3ea2a4e7KDDHb6E_T7p4_1B8U0oKUw)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Sun, 20 Apr 2003 13:47:19 +0000 (13:47 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Sun, 20 Apr 2003 13:47:19 +0000 (13:47 +0000)
dev.c, vif.h, sched.h, network.c, domain.c:
  A few bug fixes. We now look up domains in a hash rather than a linked list. TX shadow ring is smaller.

xen/common/domain.c
xen/common/network.c
xen/include/xeno/sched.h
xen/include/xeno/vif.h
xen/net/dev.c

index c4114ae8c7800352c739d9e5cf6c47b975e0ce03..7e0ba72b7392d20192c6e8a7d10dad604b493556 100644 (file)
 
 rwlock_t tasklist_lock __cacheline_aligned = RW_LOCK_UNLOCKED;
 
+#define TASK_HASH_SIZE 256
+#define TASK_HASH(_id) ((_id)&(TASK_HASH_SIZE-1))
+static struct task_struct *task_hash[TASK_HASH_SIZE];
+
 /*
  * create a new domain
  */
@@ -69,32 +73,33 @@ struct task_struct *do_newdomain(unsigned int dom_id, unsigned int cpu)
     p->max_pages = p->tot_pages = 0;
     write_lock_irqsave(&tasklist_lock, flags);
     SET_LINKS(p);
+    p->next_hash = task_hash[TASK_HASH(dom_id)];
+    task_hash[TASK_HASH(dom_id)] = p;
     write_unlock_irqrestore(&tasklist_lock, flags);
 
     return(p);
 }
 
 
-/* Get a pointer to the specified domain.  Consider replacing this
- * with a hash lookup later.
- *
- * Also, kill_other_domain should call this instead of scanning on its own.
- */
 struct task_struct *find_domain_by_id(unsigned int dom)
 {
-    struct task_struct *p = &idle0_task;
-
-    read_lock_irq(&tasklist_lock);
-    do {
-        if ( (p->domain == dom) ) {
-            get_task_struct(p); /* increment the refcnt for caller */
-            read_unlock_irq(&tasklist_lock);
-            return (p);
+    struct task_struct *p;
+    unsigned long flags;
+
+    read_lock_irqsave(&tasklist_lock, flags);
+    p = task_hash[TASK_HASH(dom)];
+    while ( p != NULL )
+    {
+        if ( p->domain == dom )
+        {
+            get_task_struct(p);
+            break;
         }
-    } while ( (p = p->next_task) != &idle0_task );
-    read_unlock_irq(&tasklist_lock);
+        p = p->next_hash;
+    }
+    read_unlock_irqrestore(&tasklist_lock, flags);
 
-    return 0;
+    return p;
 }
 
 
@@ -243,14 +248,20 @@ void free_all_dom_mem(struct task_struct *p)
 /* Release resources belonging to task @p. */
 void release_task(struct task_struct *p)
 {
+    struct task_struct **pp;
+    unsigned long flags;
+
     ASSERT(p->state == TASK_DYING);
     ASSERT(!p->has_cpu);
 
     printk("Releasing task %d\n", p->domain);
 
-    write_lock_irq(&tasklist_lock);
+    write_lock_irqsave(&tasklist_lock, flags);
     REMOVE_LINKS(p);
-    write_unlock_irq(&tasklist_lock);
+    pp = &task_hash[TASK_HASH(p->domain)];
+    while ( *pp != p ) *pp = (*pp)->next_hash;
+    *pp = p->next_hash;
+    write_unlock_irqrestore(&tasklist_lock, flags);
 
     /*
      * This frees up blkdev rings. Totally safe since blkdev ref counting
index e7111fa0f3ffa482e68923837fed2f02aa68b17b..51c56a8f856940b38c42bd7dd18e18ddb75b26ef 100644 (file)
@@ -148,6 +148,9 @@ void unlink_net_vif(net_vif_t *vif)
     unsigned long flags;
     int i;
 
+    if ( vif == NULL )
+        return;
+
     for ( i = 0; i < MAX_DOMAIN_VIFS; i++ )
         if ( vif->domain->net_vif_list[i] == vif )
             vif->domain->net_vif_list[i] = NULL;
index 9f760e5e7fa71fe36cb8ab8f40af99d95e29e32d..323c201d9359ed70ffaf9f6b3a4402d1c1c30332 100644 (file)
@@ -145,7 +145,7 @@ struct task_struct {
      */
     struct mm_struct *active_mm;
     struct thread_struct thread;
-    struct task_struct *prev_task, *next_task;
+    struct task_struct *prev_task, *next_task, *next_hash;
     
     unsigned long flags;
 
index b0dc6c645eea7cfea45e3ab07776c03911eba0e3..ac5e1f35a1ba4b484da9b183feb44af3aaad0924 100644 (file)
 
 typedef struct rx_shadow_entry_st 
 {
-    /* IN vars */
     unsigned short id;
+    unsigned short flush_count; /* 16 bits should be enough */
     unsigned long  pte_ptr;
     unsigned long  buf_pfn;
-    /* PRIVATE vars */
-    unsigned long  flush_count;
 } rx_shadow_entry_t;
 
 typedef struct tx_shadow_entry_st 
 {
-    /* IN vars */
     unsigned short id;
+    unsigned short size;
     void          *header;
     unsigned long  payload;
-    /* OUT vars */
-    unsigned short size;
-    unsigned char  status;
 } tx_shadow_entry_t;
 
 typedef struct net_vif_st {
index c19fad62a205e3b13121b53f9dfd548610038728..846a9e13d1f2d45fd830d588311684e00af5c687 100644 (file)
@@ -559,7 +559,7 @@ void deliver_packet(struct sk_buff *skb, net_vif_t *vif)
      * network driver that called us should also have no nasty locks.
      */
     rx = vif->rx_shadow_ring + vif->rx_cons;
-    if ( rx->flush_count == 
+    if ( rx->flush_count == (unsigned short)
          atomic_read(&tlb_flush_count[vif->domain->processor]) )
         flush_tlb_cpu(vif->domain->processor);
 
@@ -706,7 +706,7 @@ static void tx_skb_release(struct sk_buff *skb)
 
     tx = vif->tx_shadow_ring + vif->tx_cons;
     vif->tx_cons = TX_RING_INC(vif->tx_cons);
-    make_tx_response(vif, tx->id, tx->status);
+    make_tx_response(vif, tx->id, RING_STATUS_OK);
 
     put_vif(vif);
 }
@@ -749,8 +749,6 @@ static void net_tx_action(unsigned long unused)
         if ( vif->tx_idx != vif->tx_prod )
             add_to_net_schedule_list_tail(vif);
 
-        ASSERT(tx->status == RING_STATUS_OK);
-
         skb->destructor = tx_skb_release;
         
         skb->head = skb->data = tx->header;
@@ -1871,7 +1869,6 @@ long do_net_update(void)
             {
                 vif->tx_shadow_ring[j].id     = tx.id;
                 vif->tx_shadow_ring[j].size   = tx.size;
-                vif->tx_shadow_ring[j].status = RING_STATUS_OK;
                 vif->tx_shadow_ring[j].header = 
                     kmem_cache_alloc(net_header_cachep, GFP_KERNEL);
                 if ( vif->tx_shadow_ring[j].header == NULL )
@@ -1968,7 +1965,7 @@ long do_net_update(void)
             vif->rx_shadow_ring[j].id          = rx.id;
             vif->rx_shadow_ring[j].pte_ptr     = rx.addr;
             vif->rx_shadow_ring[j].buf_pfn     = buf_pfn;
-            vif->rx_shadow_ring[j].flush_count = 
+            vif->rx_shadow_ring[j].flush_count = (unsigned short) 
                 atomic_read(&tlb_flush_count[smp_processor_id()]);
             j = RX_RING_INC(j);